﻿package {
	import flash.display.MovieClip
	import playerio.*
	import flash.geom.Rectangle;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.utils.Dictionary;
	import Raticate;
	import Bullet;
	import ui.Prompt;
	import ui.Chat;
	import flash.errors.MemoryError;

	public class MyGame extends MovieClip{
		public static const HAUT:Number = 0;
		public static const DROITE:Number = 1;
		public static const BAS:Number = 2;
		public static const GAUCHE:Number = 3;
		public static const ZERGLING:Number =0;
		public static const HYDRALISK:Number =1;
		public static const ULTRALISK:Number =2;
		
		//Create a player list;
		var PlayersList:Dictionary = new Dictionary();
		
		//Create a monster List
		var MonstersList:Dictionary = new Dictionary();
		
		//Create a bullet List
		var BulletsList:Dictionary = new Dictionary();
		
		var ChatBox:Chat;
	
		function MyGame(){
			stop();
			
			var p:Prompt = new Prompt(stage, "What's your name?", "Guest-" + (Math.random()*9999<<0), function(name:String){
				PlayerIO.connect(
					stage,								//Referance to stage
					"protect-the-fortress-mper70w20irykbyusz2na",			//Game id (Get your own at playerio.com)
					"public",							//Connection id, default is public
					name,						        //Username
					"",									//User auth. Can be left blank if authentication is disabled on connection
					null,								//Current PartnerPay partner.
					handleConnect,						//Function executed on successful connect
					handleError							//Function executed if we recive an error
				);
			});
		}
		
		private function handleConnect(client:Client):void{
			trace("Sucessfully connected to player.io");
			
			//Set developmentsever (Comment out to connect to your server online)
			client.multiplayer.developmentServer = "localhost:8184";
			
			//Create pr join the room test
			client.multiplayer.createJoinRoom(
				"test",								//Room id. If set to null a random roomid is used
				"MyCode",							//The game type started on the server
				true,								//Should the room be visible in the lobby?
				{},									//Room data. This data is returned to lobby list. Variabels can be modifed on the server
				{},									//User join data
				handleJoin,							//Function executed on successful joining of the room
				handleError							//Function executed if we got a join error
			);
		}
		
		
		private function handleJoin(connection:Connection):void{
			trace("Sucessfully connected to the multiplayer server");
			gotoAndStop(2);
			
			//Creates the chat box
			/*ChatBox = new Chat(stage,connection);
			ChatBox.doubleClickEnabled = true;
			ChatBox.name="allo";
			addChild(ChatBox);
			this.ChatBox.sendMessage("allo les amis")*/
			connection.send("MyNameIs",this.name);

			var r:Raticate = new Raticate();
			this.addChild(r);
			//Stage events
			stage.addEventListener(KeyboardEvent.KEY_DOWN,function(k:KeyboardEvent){
				switch(k.keyCode)
				{
					case 38:
					case 87:
					r.movePlayer(HAUT);
					connection.send("Move",r.getId(),HAUT);
					break;
					case 39:
					case 68:
					r.movePlayer(DROITE);
					connection.send("Move",r.getId(),DROITE);
					break;
					case 40:
					case 83:
					r.movePlayer(BAS);
					connection.send("Move",r.getId(),BAS);
					break;
					case 37:
					case 65:
					r.movePlayer(GAUCHE);
					connection.send("Move",r.getId(),GAUCHE);
					break;
					case 32:
					connection.send("Fire",Raticate.BAS);
					break;
				}
			});
			
			//Add message handler for monster spawns
			connection.addMessageHandler("SpawnMonster",handlerMonsters);
			
			//Add message handler for monster death.
			connection.addMessageHandler("KillMonster",killMonster);
			
			//Add Chat message handler
			connection.addMessageHandler("Chat",handleChat);
			
			//Add disconnect listener
			connection.addDisconnectHandler(handleDisconnect);
					
			//Add listener for messages of the type "hello"
			connection.addMessageHandler("hello", function(m:Message){
				trace("Recived a message with the type hello from the server");			 
			})
			
			//List all players that are already in the server
			connection.addMessageHandler("CurrentUsers", function(m:Message,uName:String,p_X:Number,p_Y:Number,p_Id:Number){
				trace("Recived a message with the type hello from the server");
				var newR:Raticate = new Raticate();
				newR.setPosition(p_X,p_Y);
				newR.setName(uName);
				PlayersList[p_Id] = newR;
				addChild(PlayersList[p_Id]);
			})
			connection.addMessageHandler("Name", function(m:Message,p_Id:Number,p_Name:String){
				r.setName(p_Name); 
				r.setId(p_Id);
				//Add into the dictionary
				PlayersList[p_Id] = r;
			});
			
			//Add message listener for users joining the room
			connection.addMessageHandler("UserJoined", newUser);
			
			//Add message listener for users leaving the room
			connection.addMessageHandler("UserLeft", function(m:Message, userid:uint){
				trace("Player with the userid", userid, "just left the room");
				removeChild(PlayersList[userid]);
				PlayersList[userid] = null;
			})
			
			//Listen to all messages using a private function
			connection.addMessageHandler("*", handleMessages)
			
			connection.addMessageHandler("start", function(m:Message, userid:String, username:String, x:int, y:int){
				//Add a new player
				var newPlayer:Raticate = new Raticate();
			});
			
			connection.addMessageHandler("CurrentUser",displayCurrent);
			
			//Add moving handler
			connection.addMessageHandler("Move",movePlayer);
			
			//Add fire handler
			connection.addMessageHandler("Fire",fireHandler);
			
			//Add bullet hit handler
			connection.addMessageHandler("BulletHit",bulletHit);
			
		}
		
		public function displayCurrent(m:Message,p_Id:Number,userName:String,p_X:Number,p_Y:Number)
		{
			var newR:Raticate = new Raticate();
			newR.setName(userName);
			newR.setId(p_Id);
			newR.setPosition(p_X,p_Y);
			this.PlayersList[p_Id] = newR;
			addChild(PlayersList[p_Id]);
		}
		
		public function movePlayer(m:Message,p_UID:Number,p_Direction:Number):void
		{
			var r:Raticate = this.PlayersList[p_UID];
			r.movePlayer(p_Direction);
			this.PlayersList[p_UID] = r;
		}
		
		public function moveMonster(m:Message,p_Id:Number,p_Direction:Number):void
		{
			Monster
		}
		
		private function newUser(m:Message,p_Id:Number,p_Name:String)
		{
			trace("Player with the userid", p_Id, "just joined the room");
			var newR:Raticate = new Raticate();
			newR.setName(p_Name);
			newR.setId(p_Id);
			this.PlayersList[p_Id] = newR;
			this.addChild(newR);
		}
		
		private function handleMessages(m:Message){
			trace("Recived the message", m)
		}
		
		private function handleDisconnect():void{
			trace("Disconnected from server")
		}
		
		private function handleError(error:PlayerIOError):void{
			trace("got",error)
			gotoAndStop(3);

		}
		 
		private function handleChat(m:Message,p_Message:String):void
		{
			//this.ChatBox.sendMessage(p_Message);
		}
		
		private function fireHandler(m:Message,p_Id:Number,p_BId:Number,p_Direction:Number):void
		{
			this.BulletsList[p_BId] = Raticate(this.PlayersList[p_Id]).fire(p_Direction);
			addChild(BulletsList[p_BId]);
		}
		
		private function handlerMonsters(m:Message,p_Id:Number,p_Type:Number,p_X:Number,p_Y:Number):void
		{
			var mon:Monster;
			
			switch(p_Type)
			{
				case ZERGLING :
				mon = new Zergling(p_X,p_Y);
				break;
				case HYDRALISK :
				mon = new Hydralisk(p_X,p_Y);
				break;
				case ULTRALISK :
				mon = new Ultralisk(p_X,p_Y);
				break;
			}
			//Add the monster to the monster list
			MonstersList[p_Id] = mon;
			this.addChild(mon);
			stage.addEventListener(Event.ENTER_FRAME,function (e:Event){mon.move(HAUT);});
			
		}
	
		public function killMonster(m:Message,p_Id:Number)
		{
			trace(Raticate(PlayersList[1]).getX()+", "+Raticate(PlayersList[1]).getY());
			removeChild(MonstersList[p_Id]);
			MonstersList[p_Id] = null;
		}
		
		public function bulletHit (m:Message,p_Id:Number)
		{
			removeChild(BulletsList[p_Id]);
			BulletsList[p_Id] = null;
		}
	}
}
